import { defineStore } from 'pinia'
import { getToken, removeToken, setToken } from '../utils/token-utils'
import type { UserInfoState } from './interface'
import { ElMessage } from 'element-plus'
import { staticRoutes, anyRoutes, allAsyncRoutes } from '@/router/routes'
import { getUserInfoApi, loginApi } from '@/api/acl/login'
import { cloneDeep } from 'lodash'
import type { RouteRecordRaw } from 'vue-router'
import router from '@/router'
function filterAsyncRoutes(
  asyncRoutes: RouteRecordRaw[],
  routeNames: string[]
) {
  const newAsyncRoutes = asyncRoutes.filter((routeObj) => {
    // 获取路由名字
    const name = routeObj.name

    // 先判断一下最外层的能不能用 外层不能用，则不进入内层
    // 也相当于是递归停止的条件
    if (!routeNames.includes(name as string)) {
      return false
    }

    if (routeObj.children?.length) {
      routeObj.children = filterAsyncRoutes(routeObj.children, routeNames)
    }

    return true
  })

  return newAsyncRoutes
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {
  state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    roles: [],
    buttons: [],
    routeNames: [],
    menuRoutes: [],
  }),

  actions: {
    async login(username: string, password: string) {
      // return new Promise((resolve, reject) => {
      //   setTimeout(() => {
      //     if (username==='admin' && password==='111111') {
      //       const token = 'token-atguigu'
      //       setToken(token)
      //       this.token = token
      //       resolve(token)
      //     } else {
      //       reject(new Error('用户名或密码错误!'))
      //       ElMessage.error('用户名或密码错误!')
      //     }
      //   }, 1000)
      // })
      // 真正的向后台服务器发送请求 去实现登陆
      const { token } = await loginApi(username, password)
      // 存储到本地存储当中的token
      setToken(token)
      this.token = token // 存在内存当中的
    },

    async getInfo() {
      // return new Promise((resolve, reject) => {
      //   setTimeout(() => {
      //     this.name = 'admin'
      //     this.avatar = 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif'
      //     this.menuRoutes = staticRoutes
      //     resolve({name: this.name, avatar: this.avatar, token: this.token})
      //   }, 1000)
      // })
      const result = await getUserInfoApi()
      this.name = result.name
      this.avatar = result.avatar
      this.buttons = result.buttons
      this.roles = result.roles
      this.routeNames = result.routes
      // 根据服务器端响应回来的数据动态添加路由
      this.setRoutes(result.routes)

      // menusRoutes表示侧边要显示的菜单项导航
      // this.menuRoutes = staticRoutes
      // console.log('aa',result)
    },

    reset() {
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.name = ''
      this.avatar = ''
    },
    setRoutes(routeNames: string[]) {
      // 根据服务器端响应回来的数据，以及分割出来的异步路由数组，实现异步过滤效果
      // 过滤出来用户有权限访问的路由信息
      const asyncRoutes = filterAsyncRoutes(
        cloneDeep(allAsyncRoutes),
        routeNames
      )
      // console.log('ass',asyncRoutes)
      // 由于路由对象是一个复杂数据类型，不要直接进行操作，为了避免影响，此时需要使用深度克隆
      // 根据过滤完的异步 路由数组 来遍历动态注入
      addRoutes(asyncRoutes)
      addRoutes(anyRoutes)

      // 左侧导航栏展示信息
      this.menuRoutes = [...staticRoutes, ...asyncRoutes, ...anyRoutes]
    },
  },
})

function addRoutes(asyncRoutes: RouteRecordRaw[]) {
  asyncRoutes.forEach((routeObj) => {
    router.addRoute(routeObj)
  })
}
